import { spawn } from "node:child_process";
import path from "node:path";
import { getFiles } from "./Utils";
import * as iconv from 'iconv-lite';
import * as fs from "fs-extra";
const PROJECT_ROOT = path.resolve(__dirname, '../..');

// 定义 TexturePacker JSON 数据结构
interface TexturePackerFrame {
    filename: string;
    frame: { x: number; y: number; w: number; h: number };
    rotated: boolean;
    trimmed: boolean;
    spriteSourceSize: { x: number; y: number; w: number; h: number };
    sourceSize: { w: number; h: number };
}

interface TexturePackerMeta {
    app: string;
    version: string;
    image: string;
    format: string;
    size: { w: number; h: number };
    scale: string;
    smartupdate: string;
}

interface TexturePackerJSON {
    frames: TexturePackerFrame[];
    meta: TexturePackerMeta;
}

// 将 TexturePacker JSON 转换为 BMFont 格式
function convertToBMFont(jsonData: TexturePackerJSON, outputDir: string) {
    const { frames, meta } = jsonData;

    // 过滤掉非字符帧（如 testTxt.png）
    const charFrames = frames.filter(frame =>
        frame.filename.endsWith('.png') && path.basename(frame.filename, '.png').length == 1
    );

    // 计算最大字符高度（用于行高）
    const maxHeight = Math.max(...charFrames.map(frame => frame.sourceSize.h));
    const maxWidth = Math.max(...charFrames.map(frame => frame.sourceSize.w));

    // 创建 BMFont 文件内容
    let fntContent = `info face=${meta.image.replace('.png', '')} size=${Math.max(maxHeight, maxWidth)} bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=0,0,0,0 spacing=1,1\n`;
    fntContent += `common lineHeight=${maxHeight} base=${Math.round(maxHeight * 0.8)} scaleW=${meta.size.w} scaleH=${meta.size.h} pages=1 packed=0\n`;
    fntContent += `page id=0 file="${meta.image}"\n`;
    fntContent += `chars count=${charFrames.length}\n`;

    // 添加每个字符的定义
    charFrames.forEach(frame => {
        const char = path.basename(frame.filename, '.png');
        const charCode = char.length === 1 ? char.charCodeAt(0) : 0;
        let yoffset = `${(maxHeight - frame.spriteSourceSize.h) / 2} `;
        fntContent += `char id=${charCode} `;
        fntContent += `x=${frame.frame.x} `;
        fntContent += `y=${frame.frame.y} `;
        fntContent += `width=${frame.frame.w} `;
        fntContent += `height=${frame.frame.h} `;
        fntContent += `xoffset=${0} `;
        fntContent += `yoffset=${yoffset} `;
        fntContent += `xadvance=${frame.frame.w} `;
        fntContent += `page=0 `;
        fntContent += `chnl=15\n`;
    });

    // 保存文件
    const fntPath = path.join(outputDir, path.basename(meta.image, '.png') + '.fnt');
    fs.writeFileSync(fntPath, fntContent, 'utf8');

    console.log(`已生成艺术字文件: ${fntPath}`);
    return fntPath;
}

// 获取当前执行文件的目录
const exe = path.join(PROJECT_ROOT, "libs", "texturepack", "bin", "TexturePacker.exe");
export async function BitmapFont(inputDir: string, outputDir: string) {
    if(!fs.existsSync(outputDir)){
        console.log(`${outputDir} 目录不存在`);
        return
    }
    let imgs: string[] = await getFiles(inputDir, "png", false)
    if (imgs.length < 2) {
        console.log("图片数量少于 2，无法生成 BitmapFont");
        return
    }
    let jsonName = `${path.basename(inputDir)}.json`
    let pngName = `${path.basename(inputDir)}.png`
    outputDir = outputDir || path.join(inputDir, "out")
    let jsonPath = path.join(outputDir, jsonName)
    let pngPath = path.join(outputDir, pngName)
    let args = [
        "--size-constraints",
        "AnySize",
        "--max-width",
        "2048",
        "--max-height",
        "2048",
        "--format",
        "json-array",
        "--data",
        jsonPath,
        "--sheet",
        pngPath,
        "--disable-rotation",
        ...imgs
    ]


    const child = spawn(exe, args, {
        stdio: 'inherit',
    });

    // 等待 TexturePacker 完成
    await new Promise<void>((resolve, reject) => {
        child.on('close', (code) => {
            if (code === 0) resolve();
            else reject(new Error(`TexturePacker 退出码: ${code}`));
        });
    });

    const buffer = fs.readFileSync(jsonPath);
    const content = iconv.decode(buffer, 'gbk');
    // 读取 JSON 数据
    let jsonData = JSON.parse(content) as TexturePackerJSON;

    // 转换为艺术字格式
    const _outputDir = path.dirname(jsonPath);
    convertToBMFont(jsonData, _outputDir);
    fs.removeSync(jsonPath);
}